from perceptron import *
from common import *
import numpy as np


if __name__ == '__main__':
    np.random.seed(2)

    data = read_data_by_labels('TrainSamples.csv', 'TrainLabels.csv')
    perceptrons = [Perceptron(np.random.sample(18)) for i in range(10)]

    for i in range(10):
        pos_samples = data[i]
        neg_samples = []
        for j in range(10):
            if j != i:
                for sample in data[j]:
                    new_sample = sample + []
                    for k in range(len(new_sample)):
                        new_sample[k] = -(new_sample[k])
                    neg_samples.append(new_sample)
        samples = np.array(pos_samples + neg_samples)
        print('Training perceptron ' + str(i))
        perceptrons[i].train(samples, lr=1e-8)
        # exit()

    # # Train statistics
    # print()
    # print('Train statistics')
    # num_correct_all_labels = 0
    # num_total_all_labels = 0
    # for label in range(10):
    #     samples = data[label]
    #     num_correct = 0
    #     for sample in samples:
    #         sample = np.array(sample)
    #         scores = [perceptron.classify(sample) for perceptron in perceptrons]
    #         pred = np.argmax(scores)
    #         if pred == label:
    #             num_correct += 1
    #     num_total = len(samples)
    #     accuracy = num_correct / num_total
    #     print('Label ' + str(label) + ', num_correct = ' + str(num_correct) + ', num_total = ' + str(num_total) + ', accuracy = ' + str(accuracy))
    #     num_correct_all_labels += num_correct
    #     num_total_all_labels += num_total
    # accuracy = num_correct_all_labels / num_total_all_labels
    # print('All labels, num_correct = ' + str(num_correct_all_labels) + ', num_total = ' + str(num_total_all_labels) + ', accuracy = ' + str(accuracy))

    # lr = 1e-10, num_correct = 18522, num_total = 30000, accuracy = 0.6174
    # lr = 1e-9,  num_correct = 20159, num_total = 30000, accuracy = 0.6719666666666667
    # lr = 1e-8,  num_correct = 21631, num_total = 30000, accuracy = 0.7210333333333333
    # lr = 1e-7,  num_correct = 21260, num_total = 30000, accuracy = 0.7086666666666667
    # lr = 1e-6,  num_correct = 15726, num_total = 30000, accuracy = 0.5242
    # lr = 1e-5,  num_correct = 18606, num_total = 30000, accuracy = 0.6202
    # lr = 1e-4,  num_correct = 18579, num_total = 30000, accuracy = 0.6193

    # Test statistics
    test_data = read_data_by_labels('TestSamples.csv', 'TestLabels.csv')
    print()
    print('Test statistics')
    num_correct_all_labels = 0
    num_total_all_labels = 0
    for label in range(10):
        samples = test_data[label]
        num_correct = 0
        for sample in samples:
            sample = np.array(sample)
            scores = [perceptron.classify(sample) for perceptron in perceptrons]
            pred = np.argmax(scores)
            if pred == label:
                num_correct += 1
        num_total = len(samples)
        accuracy = num_correct / num_total
        print('Label ' + str(label) + ', num_correct = ' + str(num_correct) + ', num_total = ' + str(num_total) + ', accuracy = ' + str(accuracy))
        num_correct_all_labels += num_correct
        num_total_all_labels += num_total
    accuracy = num_correct_all_labels / num_total_all_labels
    print('All labels, num_correct = ' + str(num_correct_all_labels) + ', num_total = ' + str(num_total_all_labels) + ', accuracy = ' + str(accuracy))

    # lr = 1e-8
    # Label 0, num_correct = 885, num_total = 1009, accuracy = 0.8771060455896927
    # Label 1, num_correct = 1014, num_total = 1150, accuracy = 0.8817391304347826
    # Label 2, num_correct = 669, num_total = 963, accuracy = 0.6947040498442367
    # Label 3, num_correct = 664, num_total = 1021, accuracy = 0.6503428011753183
    # Label 4, num_correct = 623, num_total = 960, accuracy = 0.6489583333333333
    # Label 5, num_correct = 520, num_total = 917, accuracy = 0.5670665212649946
    # Label 6, num_correct = 806, num_total = 974, accuracy = 0.8275154004106776
    # Label 7, num_correct = 883, num_total = 1047, accuracy = 0.8433619866284623
    # Label 8, num_correct = 630, num_total = 965, accuracy = 0.6528497409326425
    # Label 9, num_correct = 450, num_total = 994, accuracy = 0.45271629778672035
    # All labels, num_correct = 7144, num_total = 10000, accuracy = 0.7144
